home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / TOPMAP.ZIP / TOPMAP.PAS
Pascal/Delphi Source File  |  1987-09-22  |  20KB  |  544 lines

  1.  
  2. {=========================================================================
  3.  The following two Turbo Pascal programs were written by Teuvo Kohonen
  4.  from Finland and were distributed at the First International Conference
  5.  on Neural Networks in San Diego, June 1987.
  6.  =========================================================================}
  7.  
  8. program ToPreM1 (output) ;
  9. { Demonstration program of Topology Preserving Mappings:
  10.   linear topology, input and weight vectors two-dimensional
  11.   Copyright (c) Teuvo Kohonen, June 1987 }
  12.  
  13. const
  14.   iMax = 35 ; {number of units minus one in the array}
  15.   jMax = 1 ; {two-dimensional input and weight vectors}
  16.   A0 = 0.3 ; {initializing value for the forgetting constant}
  17.   G = 0.2 ; {adjusting parameter for the width of the initial value for the
  18.             weights}
  19.  
  20. type
  21.   DensityFunctions = (Square, triangle, cross, lettera, letterk, lettery) ;
  22.   {area options where input vectors will be uniformly distributed}
  23.  
  24. var
  25.   Tk : integer ; {number of time instances or steps elapsed since the
  26.                  beginning of the process}
  27.   A : real ; {the alpha function a=a(Tk) is A piecewise linearly decreasing
  28.              function of Tk}
  29.   T1 : integer ; {T1 is the end of the initial time interval during which
  30.                  a(Tk) decreases linearly ; thereafter A new greater T1
  31.                  value is set to define the next interval etc.}
  32.   t : integer ; {the number of time instances elapsed since the beginning of
  33.                 the interval described above}
  34.   T2 : integer ; {defines the interval for graphic display update, selected
  35.                  small in the beginning but becomes larger in each linear
  36.                  segment}
  37.   A1, A2 : real ; {the forgetting constant A1 keeps track of a(t) in A linear
  38.                   segment, A2 is always 1-A1}
  39.   W0 : 0..iMax ; {initializing value for the kernel width}
  40.   w : 0..iMax ; {defines the topological neighborhood which is selected wide
  41.                 in the beginning (with W0) and then it is let to shrink with
  42.                 time Tk}
  43.   H1, h, V1, V : 0..iMax ; {indices for the kernel units}
  44.   i : 0..iMax ; j : 0..jMax ; {indices for vectors defined below}
  45.   M : array [0..iMax,0..jMax] of real ; {vector of input weights (memory)}
  46.   X : array [0..jMax] of real ; {vector of input signals}
  47.   N : array [0..iMax] of real ; {0.5*Squared norms of M-vectors used in the
  48.                                 short-cut computation of the best-matching
  49.                                 unit selection}
  50.   Y : array [0..iMax] of real ; {vector of output signals}
  51.   C : 0..iMax ; {index of best-matching unit}
  52.   MinY : real ; {MinY = y[c]}
  53.   DensityFunction : DensityFunctions ; {input vector density function}
  54.  
  55. procedure askDensityFunction ; {asks input vector density function}
  56. var d : char ;
  57. begin {ask input vector density function}
  58.   writeln ('Topology Preserving Mappings:') ;
  59.   writeln ('-linear topology') ;
  60.   writeln ('-input and weight vectors two-dimensional') ;
  61.   writeln ;
  62.   writeln ('Select density function') ;
  63.   DensityFunction := Square ;
  64.   writeln ('square  s') ;
  65.   writeln ('triangle  t') ;
  66.   writeln ('cross  c') ;
  67.   writeln ('letter A  a') ;
  68.   writeln ('letter K  k') ;
  69.   write ('letter Y  y:') ;
  70.   readln (d) ;
  71.   writeln ;
  72.   case d of
  73.     's' : DensityFunction := Square ;
  74.     't' : DensityFunction := triangle ;
  75.     'c' : DensityFunction := cross ;
  76.     'a' : DensityFunction := lettera ;
  77.     'k' : DensityFunction := letterk ;
  78.     'y' : DensityFunction := lettery ;
  79.   end ;
  80. end ; {askDensityFunction}
  81.  
  82. procedure ReadInput ; {reads the vector of input signals}
  83. var
  84.   inside : boolean ;
  85. begin
  86.   repeat {impose uniform density within the framed area}
  87.     inside := false ;
  88.     x[0] := random ;
  89.     x[1] := random ;
  90.     case DensityFunction of
  91.       Square : inside := true ;
  92.       triangle : if x[1] >= 2*abs(x[0] - 0.5) then inside := true ;
  93.       cross : if (abs (x[0] - 0.5) <= 1/4) or (abs (x[1] - 0.5) <= 1/4) then
  94.                 inside := true ;
  95.       lettera : if ((x[1] - 5/16 <= 11/4 * abs (x[0] - 0.5)) and
  96.                 (x[1] + 3/8 >= 11/4*abs(x[0] - 0.5))) or
  97.                 ((x[1] >= 7/16) and (x[1] <= 11/16) and
  98.                 (x[1] - 5/16 >= 11/4*abs (x[0] - 0.5))) then inside := true ;
  99.       letterk : if (x[0] <= 2/8) or ((x[0] - 4/8 <= abs (x[1] - 0.5)) and
  100.                 (x[1] >= 4/8)) or ((x[1] >= 21/64 - 21/16*abs(x[0]-0.5)))
  101.                 then inside := true ;
  102.     end ;
  103.   until inside ;
  104. end ; {ReadInput}
  105.  
  106. function max (x, Y : integer) : integer ;
  107. begin {returns the maximum of the two integers}
  108.   if X >= Y then max := x
  109.   else max := Y ;
  110. end ; {max}
  111.  
  112. function min (x, Y : integer) : integer ;
  113. begin {returns the minimum of the two integers}
  114.   if X <= Y then min := x
  115.   else min := Y ;
  116. end ; {min}
  117.  
  118. procedure DrawDistribution ; {draws the distribution of weight vectors:
  119.                              linear array}
  120. const
  121.   cl = white ;
  122.   xw = 320 ;
  123.   yw = 160 ;
  124. var
  125.   x, y, xo, yo : integer ;
  126.  
  127.   procedure DrawLine (i : integer) ;
  128.   begin {draw A line connecting two weight vectors}
  129.     xo := X ;
  130.     X := round ((xw div 2) * (m[i,0] + m[i+1,0])) ;
  131.     yo := Y ;
  132.     Y := round ((yw div 2) * (m[i,1] + m[i+1,1])) ;
  133.     draw (xo, yo, x, y, cl) ;
  134.     draw (x-1, y-1, x+1, y-1, cl) ;
  135.     draw (x-1, y, x+1, y, cl) ;
  136.     draw (x-1, y+1, x+1, y+1, cl) ;
  137.   end ; {DrawLine}
  138.  
  139. begin {DrawDistribution}
  140.   hires ;
  141. {  graphbackground (black) ;  }
  142.   case DensityFunction of {draw the corresponding frame}
  143.     Square : begin
  144.                draw (159, 19, 481, 19, cl) ;
  145.                draw (481, 19, 481, 181, cl) ;
  146.                draw (481, 181, 159, 181, cl) ;
  147.                draw (159, 181, 159, 19, cl) ;
  148.              end ;
  149.     triangle : begin
  150.                  draw (159, 181, 481, 181, cl) ;
  151.                  draw (159, 181, 320, 20, cl) ;
  152.                  draw (481, 181, 320, 20, cl) ;
  153.                end ;
  154.     cross : begin
  155.               draw (159, 80, 280, 80, cl) ;
  156.               draw (280, 80, 280, 19, cl) ;
  157.               draw (280, 19, 360, 19, cl) ;
  158.               draw (360, 19, 360, 80, cl) ;
  159.               draw (360, 80, 481, 80, cl) ;
  160.               draw (481, 80, 481, 120, cl) ;
  161.               draw (481, 120, 360, 120, cl) ;
  162.               draw (360, 120, 360, 181, cl) ;
  163.               draw (360, 181, 280, 181, cl) ;
  164.               draw (280, 181, 280, 120, cl) ;
  165.               draw (280, 120, 159, 120, cl) ;
  166.               draw (159, 120, 159, 80, cl) ;
  167.             end ;
  168.     lettera : begin
  169.                 draw (159, 181, 280, 19, cl) ;
  170.                 draw (280, 19, 360, 19, cl) ;
  171.                 draw (360, 19, 481, 181, cl) ;
  172.                 draw (481, 181, 400, 181, cl) ;
  173.                 draw (400, 181, 369, 130, cl) ;
  174.                 draw (345, 90, 320, 50, cl) ;
  175.                 draw (320, 50, 295, 90, cl) ;
  176.                 draw (271, 130, 240, 181, cl) ;
  177.                 draw (240, 181, 159, 181, cl) ;
  178.                 draw (271, 130, 369, 130, cl) ;
  179.                 draw (295, 90, 345, 90, cl) ;
  180.               end ;
  181.     letterk : begin
  182.                 draw (159, 19, 159, 181, cl) ;
  183.                 draw (240, 100, 400, 19, cl) ;
  184.                 draw (240, 100, 400, 181, cl) ;
  185.                 draw (320, 100, 481, 19, cl) ;
  186.                 draw (320, 100, 481, 181, cl) ;
  187.                 draw (159, 19, 240, 19, cl) ;
  188.                 draw (400, 19, 481, 19, cl) ;
  189.                 draw (159, 181, 240, 181, cl) ;
  190.                 draw (400, 181, 481, 181, cl) ;
  191.               end ;
  192.     lettery : begin
  193.                 draw (159, 19, 280, 100, cl) ;
  194.                 draw (280, 100, 280, 181, cl) ;
  195.                 draw (280, 181, 360, 181, cl) ;
  196.                 draw (360, 181, 360, 100, cl) ;
  197.                 draw (360, 100, 481, 19, cl) ;
  198.                 draw (481, 19, 400, 19, cl) ;
  199.                 draw (400, 19, 320, 75, cl) ;
  200.                 draw (320, 75, 240, 19, cl) ;
  201.                 draw (240, 19, 159, 19, cl) ;
  202.               end ;
  203.   end ;
  204.   graphwindow (160, 20, 480, 180) ;
  205.   write ('Step ') ;
  206.   write (Tk) ;
  207.   write (' Alpha ') ;
  208.   write (A1:1:3) ;
  209.   X := round (xw * M [0,0]) ;
  210.   Y := round (yw * M [0,1]) ; {initialize coordinates}
  211.   for i := 0 to iMax - 1 do {draw distribution: linear array}
  212.     DrawLine (i) ;
  213. end ; {DrawDistribution}
  214.  
  215. begin {ToPreM1}
  216.   askDensityFunction ;
  217.   randomize ;
  218.   {initialize forgetting constant, kernel width and step counters}
  219.   A := A0 ;
  220.   A1 := A ;
  221.   W0 := iMax div 4 ;
  222.   T1 := 100 ;
  223.   T2 := 5 ;
  224.   t := 0 ;
  225.   Tk := 0 ;
  226.  
  227.   {*** initialize the vector of input weights M[i] with random and compute
  228.    0.5 * the Squared norm of M[i] to be used in the computation of the
  229.    best-matching unit selection***}
  230.   for i := 0 to iMax do
  231.     begin
  232.       N [i] := 0 ;
  233.       for j := 0 to jMax do
  234.         begin {adjust the width of the initial values for weights}
  235.           M [i, j] := (0.5 - g/2.0) + g*random ;
  236.           N [i] := N [i] + M [i, j] * M [i, j] ;
  237.         end ;
  238.       N [i] := N [i] / 2.0 ; {N is 0.5 * Squared norm of M}
  239.     end ; {memory vector initialization}
  240.  
  241.   DrawDistribution ; {draw the initial distribution of weight vectors}
  242.   repeat
  243.     for t := 1 to T1 do
  244.       begin
  245.         Tk := Tk + 1 ;
  246.         ReadInput ;
  247.  
  248.         {*** the best-matching unit selection ***}
  249.         MinY := N [0] ; {initializing value for the best-matching unit}
  250.         for i := 0 to iMax do
  251.           begin {use Euclidean distance}
  252.             Y [i] := N [i] ;
  253.             for j := 0 to jMax do
  254.               Y [i] := Y [i] - M [i, j] * X [j] ;
  255.             if Y [i] <= MinY then
  256.               begin {update best-matching unit and index}
  257.                 MinY := Y [i] ;
  258.                 C := i ;
  259.               end ;
  260.           end ; {best-matching unit selection}
  261.  
  262.         A1 := A * (1 - t/T1) ;
  263.         A2 := 1 - A1 ;
  264.         w := trunc (W0 * (1 - t/T1)) + 1 ; {update kernel width}
  265.  
  266.         {*** update the vector of input weights M [i] inside the kernel =
  267.          LEARNING and compute 0.5 * the Squared norm of M [i] for the best
  268.          matching unit selection ***}
  269.         for i := max (0, c-w) to min (iMax, c+w) do
  270.           begin
  271.             N [i] := 0 ;
  272.             for j := 0 to jMax do
  273.               begin
  274.                 M [i, j] := A1 * X [j] + A2 * M [i, j] ;
  275.                 N [i] := N [i] + M [i, j] * M [i, j] ;
  276.               end ;
  277.             N [i] := N [i] / 2.0 ; {N is 0.5 * the Squared norm of M}
  278.           end ; {memory vector update}
  279.  
  280.         if t mod T2 = 0 then DrawDistribution ;
  281.       end ;
  282.     A := 0.2 * A ;
  283.     W0 := 0 ;
  284.     T1 := 5 * T1 ;
  285.     T2 := 4 * T2 ; {values for the next linear segment}
  286.   until A = 0 ; { the process ends with A = 0}
  287. end.
  288.  
  289. {================== CUT HERE TO SEPARATE THE TWO PROGRAMS ================}
  290.  
  291. program ToPreM2 (output) ;
  292. { Demonstration program of Topology Preserving Mappings:
  293.   array topology two-dimensional, input and weight vectors two-dimensional
  294.   Copyright (c) Teuvo Kohonen, June 1987 }
  295.  
  296. const
  297.   iMax = 63 ; {number of units minus one in the array}
  298.   jMax = 1 ; {two-dimensional input and weight vectors}
  299.   side = 8 ; {side of array is square of iMax + 1}
  300.   A0 = 0.3 ; {initializing value for the forgetting constant}
  301.   G = 0.2 ; {adjusting parameter for the width of the initial value for the
  302.             weights}
  303.  
  304. type
  305.   DensityFunctions = (Square, triangle, cross) ;
  306.   {area options where input vectors will be uniformly distributed}
  307.  
  308. var
  309.   Tk : integer ; {number of time instances or steps elapsed since the
  310.                  beginning of the process}
  311.   A : real ; {the alpha function a=a(Tk) is A piecewise linearly decreasing
  312.              function of Tk}
  313.   T1 : integer ; {T1 is the end of the initial time interval during which
  314.                  a(Tk) decreases linearly ; thereafter A new greater T1
  315.                  value is set to define the next interval etc.}
  316.   t : integer ; {the number of time instances elapsed since the beginning of
  317.                 the interval described above}
  318.   T2 : integer ; {defines the interval for graphic display update, selected
  319.                  small in the beginning but becomes larger in each linear
  320.                  segment}
  321.   A1, A2 : real ; {the forgetting constant A1 keeps track of a(t) in A linear
  322.                   segment, A2 is always 1-A1}
  323.   W0 : 0..side ; {initializing value for the kernel width}
  324.   w : 0..side ; {defines the topological neighborhood which is selected wide
  325.                 in the beginning (with W0) and then it is let to shrink with
  326.                 time Tk}
  327.   H1, h, V1, V : 0..side ; {indices for the kernel units}
  328.   i : 0..iMax ; j : 0..jMax ; {indices for vectors defined below}
  329.   M : array [0..iMax,0..jMax] of real ; {vector of input weights (memory)}
  330.   X : array [0..jMax] of real ; {vector of input signals}
  331.   N : array [0..iMax] of real ; {0.5*Squared norms of M-vectors used in the
  332.                                 short-cut computation of the best-matching
  333.                                 unit selection}
  334.   Y : array [0..iMax] of real ; {vector of output signals}
  335.   C : 0..iMax ; {index of best-matching unit}
  336.   MinY : real ; {MinY = y[c]}
  337.   DensityFunction : DensityFunctions ; {input vector density function}
  338.  
  339. procedure askDensityFunction ; {asks input vector density function}
  340. var d : char ;
  341. begin {ask input vector density function}
  342.   writeln ('Topology Preserving Mappings:') ;
  343.   writeln ('-array topology two-dimensional') ;
  344.   writeln ('-input and weight vectors two-dimensional') ;
  345.   writeln ;
  346.   writeln ('Select density function') ;
  347.   DensityFunction := Square ;
  348.   writeln ('square   s') ;
  349.   writeln ('triangle   t') ;
  350.   write ('cross   c') ;
  351.   readln (d) ;
  352.   writeln ;
  353.   case d of
  354.     's' : DensityFunction := Square ;
  355.     't' : DensityFunction := triangle ;
  356.     'c' : DensityFunction := cross ;
  357.   end ;
  358. end ; {askDensityFunction}
  359.  
  360. procedure ReadInput ; {reads the vector of input signals}
  361. var
  362.   inside : boolean ;
  363. begin
  364.   repeat {impose uniform density within the framed area}
  365.     inside := false ;
  366.     x [0] := random ;
  367.     x [1] := random ;
  368.     case DensityFunction of
  369.       Square : inside := true ;
  370.       triangle : if x[1] >= 2*abs(x[0] - 0.5) then inside := true ;
  371.       cross : if (abs (x[0] - 0.5) <= 1/4) or (abs (x[1] - 0.5) <= 1/4) then
  372.                 inside := true ;
  373.     end ;
  374.   until inside ;
  375. end ; {ReadInput}
  376.  
  377. function max (x, Y : integer) : integer ;
  378. begin {returns the maximum of the two integers}
  379.   if X >= Y then max := x
  380.   else max := Y ;
  381. end ; {max}
  382.  
  383. function min (x, Y : integer) : integer ;
  384. begin {returns the minimum of the two integers}
  385.   if X <= Y then min := x
  386.   else min := Y ;
  387. end ; {min}
  388.  
  389. procedure DrawDistribution ; {draws the distribution of weight vectors:
  390.                              linear array}
  391. const
  392.   cl = white ;
  393.   xw = 320 ;
  394.   yw = 160 ;
  395. var
  396.   x1, x2, y1, y2 : integer ;
  397.  
  398.   procedure DrawLine (var x, y : integer ;
  399.                       i, e : integer) ;
  400.  
  401.   var xo, yo : integer;
  402.  
  403.   begin {draw A line connecting two weight vectors}
  404.     xo := X ;
  405.     X := round ((xw div 2) * (m[i,0] + m[i+e,0])) ;
  406.     yo := Y ;
  407.     Y := round ((yw div 2) * (m[i,1] + m[i+e,1])) ;
  408.     draw (xo, yo, x, y, cl) ;
  409.   end ; {DrawLine}
  410.  
  411. begin {DrawDistribution}
  412.   hires ;
  413. {  graphbackground (black) ;  }
  414.   case DensityFunction of {draw the corresponding frame}
  415.     Square : begin
  416.                draw (159, 19, 481, 19, cl) ;
  417.                draw (481, 19, 481, 181, cl) ;
  418.                draw (481, 181, 159, 181, cl) ;
  419.                draw (159, 181, 159, 19, cl) ;
  420.              end ;
  421.     triangle : begin
  422.                  draw (159, 181, 481, 181, cl) ;
  423.                  draw (159, 181, 320, 20, cl) ;
  424.                  draw (481, 181, 320, 20, cl) ;
  425.                end ;
  426.     cross : begin
  427.               draw (159, 95, 310, 19, cl) ;
  428.               draw (310, 95, 310, 19, cl) ;
  429.               draw (310, 19, 330, 19, cl) ;
  430.               draw (330, 19, 330, 95, cl) ;
  431.               draw (330, 95, 481, 95, cl) ;
  432.               draw (481, 95, 481, 105, cl) ;
  433.               draw (481, 105, 330, 105, cl) ;
  434.               draw (330, 105, 330, 181, cl) ;
  435.               draw (330, 181, 310, 181, cl) ;
  436.               draw (310, 181, 310, 105, cl) ;
  437.               draw (310, 105, 159, 105, cl) ;
  438.               draw (159, 105, 159, 95, cl) ;
  439.             end ;
  440.   end ;
  441.   graphwindow (160, 20, 480, 180) ;
  442.   write ('Step ') ;
  443.   write (Tk) ;
  444.   write (' Alpha ') ;
  445.   write (A1:1:3) ;
  446.   for h := 0 to side-1 do
  447.     begin {horizontal}
  448.       X1 := round (xw * M [h,0]) ;
  449.       Y1 := round (yw * M [h,1]) ; {initialize coordinates}
  450.       X2 := round (xw * M [side * H,0]) ;
  451.       Y2 := round (yw * M [side * H,1]) ;
  452.       drawline (x1, y1, h, side) ;
  453.       drawline (x2, y2, side * h, 1) ;
  454.       for V := 1 to side-2 do
  455.         begin {vertical}
  456.           drawline (x1, y1, side * v + h,0) ;
  457.           drawline (x1, y1, side * v + h,side) ;
  458.           drawline (x2, y2, side * h + v,0) ;
  459.           drawline (x2, y2, side * h + v,1) ;
  460.         end ;
  461.       drawline (x1, y1, side * (side-1) + h,0) ;
  462.       drawline (x2, y2, side * h + side - 1,0) ;
  463.     end ;
  464. end ; {DrawDistribution}
  465.  
  466. begin {ToPreM1}
  467.   askDensityFunction ;
  468.   randomize ;
  469.   {initialize forgetting constant, kernel width and step counters}
  470.   A := A0 ;
  471.   A1 := A ;
  472.   W0 := side div 2 ;
  473.   T1 := 1000 ;
  474.   T2 := 10 ;
  475.   t := 0 ;
  476.   Tk := 0 ;
  477.  
  478.   {*** initialize the vector of input weights M[i] with random and compute
  479.    0.5 * the Squared norm of M[i] to be used in the computation of the
  480.    best-matching unit selection***}
  481.   for i := 0 to iMax do
  482.     begin
  483.       N [i] := 0 ;
  484.       for j := 0 to jMax do
  485.         begin {adjust the width of the initial values for weights}
  486.           M [i, j] := (0.5 - g/2.0) + g*random ;
  487.           N [i] := N [i] + M [i, j] * M [i, j] ;
  488.         end ;
  489.       N [i] := N [i] / 2.0 ; {N is 0.5 * Squared norm of M}
  490.     end ; {memory vector initialization}
  491.  
  492.   DrawDistribution ; {draw the initial distribution of weight vectors}
  493.   repeat
  494.     for t := 1 to T1 do
  495.       begin
  496.         Tk := Tk + 1 ;
  497.         ReadInput ;
  498.  
  499.         {*** the best-matching unit selection ***}
  500.         MinY := N [0] ; {initializing value for the best-matching unit}
  501.         for i := 0 to iMax do
  502.           begin {use Euclidean distance}
  503.             Y [i] := N [i] ;
  504.             for j := 0 to jMax do
  505.               Y [i] := Y [i] - M [i, j] * X [j] ;
  506.             if Y [i] <= MinY then
  507.               begin {update best-matching unit and index}
  508.                 MinY := Y [i] ;
  509.                 C := i ;
  510.               end ;
  511.           end ; {best-matching unit selection}
  512.  
  513.         A1 := A * (1 - t/T1) ;
  514.         A2 := 1 - A1 ;
  515.         H1 := C mod side ;
  516.         V1 := C div side ;
  517.         w := trunc (W0 * (1 - t/T1)) + 1 ; {update kernel width}
  518.  
  519.         {*** update the vector of input weights M [i] inside the kernel =
  520.          LEARNING and compute 0.5 * the Squared norm of M [i] for the best
  521.          matching unit selection ***}
  522.         for h := max (0,h1-w) to min (side-1,h1+w) do
  523.           for V := max (0,V1-W) to min (side-1,V1+W) do
  524.             begin
  525.               i := side * V + H ;
  526.               N [i] := 0 ;
  527.               for j := 0 to jMax do
  528.                 begin
  529.                   M [i,j] := A1 * X [j] + A2 * M [i,j] ;
  530.                   N [i] := N [i] + M [i,j] * M [i,j] ;
  531.                 end ;
  532.               N [i] := N [i] / 2.0 ; {N is 0.5 * the squared norm of M}
  533.             end ; {memory vector update}
  534.  
  535.         if t mod T2 = 0 then DrawDistribution ;
  536.       end ;
  537.     A := 0.2 * A ;
  538.     W0 := 0 ;
  539.     T1 := 5 * T1 ;
  540.     T2 := 5 * T2 ; {values for the next linear segment}
  541.   until A = 0 ; { the process ends with A = 0}
  542. end.
  543.  
  544.